/**
 * Project: apollo-base-commons
 * 
 * File Created at 2016年10月25日
 * 
 * Copyright 2015-2016 dx.com Croporation Limited.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * DongXue software Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with dx.com.
 */
package com.dx.pf.commons.async.proxy;

import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;

import com.dx.pf.commons.async.pool.AsyncFutureTask;
import com.dx.pf.commons.cache.AsyncProxyCache;
import com.dx.pf.commons.constants.AsyncConstant;
import com.dx.pf.commons.log.Logger;
import com.dx.pf.commons.reflect.ReflectUtil;

/** 
* @ClassName: AsyncResultProxy 
* @Description: TODO(这里用一句话描述这个类的作用) 
* @author wuzhenfang(wzfbj2008@163.com)
* @date 2016年10月25日 下午4:48:12 
* @version V1.0 
*/
public class AsyncResultProxy implements AsyncProxy {

	private final static Logger logger = Logger.getLogger(AsyncResultProxy.class);

	private AsyncFutureTask future;

	public AsyncResultProxy(AsyncFutureTask future) {
		this.future = future;
	}

	public Object buildProxy(Object t, boolean all) {
		return buildProxy(t, AsyncConstant.ASYNC_DEFAULT_TIME_OUT, true);
	}

	public Object buildProxy(Object t, long timeout, boolean all) {
		Class<?> returnClass = t.getClass();
		if (t instanceof Class) {
			returnClass = (Class) t;
		}
		Class<?> proxyClass = AsyncProxyCache.getProxyClass(returnClass.getName());
		if (proxyClass == null) {
			Enhancer enhancer = new Enhancer();
			if (returnClass.isInterface()) {
				enhancer.setInterfaces(new Class[] { returnClass });
			} else {
				enhancer.setSuperclass(returnClass);
			}
			enhancer.setNamingPolicy(AsyncNamingPolicy.INSTANCE);
			enhancer.setCallbackType(AsyncResultInterceptor.class);
			proxyClass = enhancer.createClass();
			logger.debug("create result proxy class:" + returnClass );
			AsyncProxyCache.registerProxy(returnClass.getName(), proxyClass);
		}
		Enhancer.registerCallbacks(proxyClass, new Callback[] { new AsyncResultInterceptor(future, timeout) });
		Object proxyObject = null;
		try {
			proxyObject = ReflectUtil.newInstance(proxyClass);
		} finally {
			Enhancer.registerStaticCallbacks(proxyClass, null);
		}
		return proxyObject;
	}
}
